package com.bs.rss.common.utils;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;

import javax.sql.DataSource;

import com.bs.rss.common.model.data.Rss;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.druid.DruidPlugin;
import com.sun.syndication.feed.rss.Channel;
import com.sun.syndication.feed.rss.Description;
import com.sun.syndication.feed.rss.Guid;
import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.WireFeedOutput;
import com.sun.syndication.io.XmlReader;

/** 
 * @author  作者 E-mail: 
 * @date 创建时间：2017年4月16日 上午11:49:26 
 * @version 1.0 
 * @parameter  
 * @since  
 * @return  
 */
/***
 * rss是什么? rss是在线共享内容的一种简易方式（也叫聚合内容，Really Simple Syndication 的简称,通常在
 * 时效性比较强的内容上使用RSS订阅能更快速获取信息，网站提供RSS输出，有利于让用户获取网站内容的最
 * 新更新,其实是一种能跨平台的服务于用户的简单xml文件协议.
 * 
 * 为什么要RSS? 在这个网络知识繁华的岁月,每个人都希望能快速的知道自己关心的知识,比如我关心x站的x
 * 一个栏目,我就可以订阅该栏目的rss,如有文章发布,我就能及时的看到更新...中间的商机我就不再赘言了.
 * 
 * 
 * 目前网上的使用主要分为以下几种： 1.不同网站中blog的迁移 如ITEye的blog到ITpub blog数据的迁移 2.订阅特定网站的信息的更新
 * 如果订阅特定的网站的blog更新 3.RSS在线阅读器的使用。 通过手机等通讯工具在线阅读最新信息
 * 
 * 
 * 
 * RSS文件结构 以下以RSS2.0为例说明.rss文件的核心就是xml文件,所以首先必须符合xml的构架格式. 它是以
 * <rss version="2.0">...</rss> 这种Root形式的格式.
 * rss有一<channel>的子节点,它包含了文件的内容,在<channel>的里面,有好几个元素用以描述信息.
 * 在站点http://backend.userland.com/rss上有详细的内容,比如以下: title:标题,经常还有资料的来源信息
 * link:web站点的url地址 description:对网站的一个简单描述.
 * 每条信息用以<item>元素表示,它被包含在<channel>节点里面,每个<channel>可以有多个<item>,每个<item>节点是真正的节点信息:
 * title:列表项目的标题 link:列表项目的web url地址, description:对列表项目的简短说明, author:列表信息的作者
 * pubDate:发布时间. 这里,有一个很重要的节点就是pubDate的格式,它必须符合RFC 822的标准,查看细节
 * .开始于三个字母长度的星期,然后是每月的 天数次序,然后是3个字母的月份,然后是年份,然后是具体的时间,最后是时区.
 * 
 * 
 */

public class RSSLibJMain {
	
	public final static RSSLibJMain dao = new RSSLibJMain();

	/**
	 * 根据RSSUrl获取所有List数据
	 * 
	 * @param rssUrl
	 * @return
	 * @throws MalformedURLException 
	 */
	public List<Rss> getAllRssItemBeanList(String rssUrl, int id)  throws Exception{
			URL feedUrl = new URL(rssUrl);
			SyndFeedInput input = new SyndFeedInput();
			SyndFeed feed = input.build(new XmlReader(feedUrl));

			@SuppressWarnings("unchecked")
			List<SyndEntryImpl> entries = feed.getEntries();

			Rss item = null;
			List<Rss> rssItemBeans = new ArrayList<Rss>();

			for (SyndEntryImpl entry : entries) {
				item = new Rss();

				item.setTitle(entry.getTitle().trim());
				item.setType(feed.getTitleEx().getValue().trim());
				item.setUri(entry.getUri());
				item.setPubdate(entry.getPublishedDate());
				item.setAuthor(entry.getAuthor());
				item.setDescription(entry.getDescription().getValue());
				item.setChannelId(id);
				rssItemBeans.add(item);

			}
			return rssItemBeans;
	}
	
	public void parseXml(URL url) throws IllegalArgumentException, FeedException {
		try {
			SyndFeedInput input = new SyndFeedInput();                                        
			SyndFeed feed = null;
			URLConnection conn;
			conn = url.openConnection();
			String content_encoding = conn.getHeaderField("Content-Encoding");

			if (content_encoding != null && content_encoding.contains("gzip")) {
				System.out.println("conent encoding is gzip");
				GZIPInputStream gzin = new GZIPInputStream(conn.getInputStream());
				feed = input.build(new XmlReader(gzin));
			} else {
				feed = input.build(new XmlReader(conn.getInputStream()));
			}

			@SuppressWarnings("rawtypes")
			List entries = feed.getEntries();// 得到所有的标题<title></title>
			for (int i = 0; i < entries.size(); i++) {
				SyndEntry entry = (SyndEntry) entries.get(i);
				
				System.out.println(entry.getTitle());
			}
			System.out.println("feed size:" + feed.getEntries().size());

		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public String createXml(List<Rss> l, com.bs.rss.common.model.data.Channel c) throws RuntimeException, FeedException {
		/*
		 * 根据Channel源码提供的英文,Channel对象有两个构造器，一个默认的无参构造器用于clone对象，一个是有参的
		 * 我们自己指定的必须使用有参数的（因为我们需要许可证），指构造方法必须要创建一个type（版本），这个type不能随便写，
		 * 必须要以rss_开头的版本号 Licensed under the Apache License, Version 2.0 (the
		 * "License"); 因为当前版本是2.0，所以就是rss_2.0，必须是rss_2.0否则会抛异常，该源码中写的已经很明白。
		 */
		Channel channel = new Channel("rss_2.0");
		channel.setTitle(c.getName());// 网站标题
		channel.setDescription("描述");// 网站描述
		channel.setLink("www.rss.net");// 网站主页链接
		channel.setUri(c.getUrl());// 网站主页链接
		channel.setEncoding("utf-8");// RSS文件编码
		channel.setLanguage("zh-cn");// RSS使用的语言
		channel.setTtl(5);// time to live的简写，在刷新前当前RSS在缓存中可以保存多长时间（分钟）
		channel.setCopyright("版权声明");// 版权声明
		channel.setPubDate(c.getCtime());// RSS发布时间
		List<Item> items = new ArrayList<Item>();// 这个list对应rss中的item列表
		Item item ;
		
		for(Rss r: l){
			item= new Item();// 新建Item对象，对应rss中的<item></item>
			item.setAuthor(r.getAuthor());// 对应<item>中的<author></author>
			item.setTitle(r.getTitle());// 对应<item>中的<title></title>
			item.setGuid(new Guid());// GUID=Globally Unique Identifier
										// 为当前新闻指定一个全球唯一标示，这个不是必须的
			item.setPubDate(r.getPubdate());// 这个<item>对应的发布时间
			item.setComments("注释");// 代表<item>节点中的<comments></comments>
			// 新建一个Description，它是Item的描述部分
			Description description = new Description();
			description.setValue(r.getDescription());// <description>中的内容
			item.setDescription(description);// 添加到item节点中
			items.add(item);// 代表一个段落<item></item>，
			channel.setItems(items);
		}
		// 用WireFeedOutput对象输出rss文本
		WireFeedOutput out = new WireFeedOutput();
		String s = null;
		try {
			 s = out.outputString(channel);
			System.out.println(out.outputString(channel));
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (FeedException e) {
			e.printStackTrace();
		}
		return s;

	}
    public static DataSource getDataSource() {
        PropKit.use("config.properties");
        DruidPlugin dbPlugin=new DruidPlugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password"));
        dbPlugin.start();

        return dbPlugin.getDataSource();
    }
    
	public static void main(String[] args) throws Exception {

		String str = "https://www.zhihu.com/rss";
 
		RSSLibJMain rssPrase = new RSSLibJMain();

		rssPrase.getAllRssItemBeanList(str, 1);

		
		 
	}
}